package com.myk.game.gobangchess.rooms;

import com.myk.game.gobangchess.Room;
import com.myk.game.gobangchess.constants.BoardStyleData;
import com.myk.game.gobangchess.constants.ColorCost;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.signs.AroundSign;
import com.myk.game.gobangchess.signs.ColorSign;

import java.util.ArrayList;
import java.util.List;

/**
 * 玉攻棋
 */
// 即便会写一点注释(给作者自己写的时候看的)，可读性也不会好

public class PenteRoom extends Room {
    public PenteRoom(String roomName) {
        super(roomName, "1978年外国人推出五子棋变体，外国有联盟定期举办比赛，国外新棋界仅次于hex的第二梯队。", "玉攻棋",BoardStyleData.getGoBangStyle(19,19), true, true);
    }

    @Override
    public String getRuleText() {
        return
                "    19*19棋盘，白先黑后，双方轮流落一子\n" +
                "    落了一子后，若与己方的另一棋子间恰好两格且均为对方棋子，则移除那两枚对方棋子，并己方加1分\n" +
                "    注意：只有落子方能发生吃子，落子本身不会被对方移走\n "    +
                "获胜条件：五子连珠或获得五分\n" +
                "    棋盘下满且没有提子和棋\n" +
                "平衡性措施：白第一手只能落在正中间(程序帮白方玩家先落了)\n" +
                "    白第二手不能走在棋盘中心的5*5区域";
    }
    @Override
    protected void onStartPrepare() {
        step=1;
        curGrids[9][9] = 2;
        blackScore = 0;
        whiteScore = 0;
        noticeBlackMove();
    }
    @Override
    public void doRule(int row, int col, int value) {
        if (curGrids[row][col] != 0) return; //只能落在空格处
        if (step == 2){ //白方第二步
            if (row<7 || col<7 || row>11 || col>11){ //只能落在中心5*5区域之外
                curGrids[row][col] = 2;
                stepAdd();
                signList.clear();
                List<Integer> ids = new ArrayList<>();
                ids.add(getIndex(row,col));
                signList.add(new AroundSign(ids,"#00000000","#6600FF00",1.2f));
                noticeBlackMove();
            }
        }
        else { //之后落子逻辑通用
            //落子
            curGrids[row][col] = value;
            stepAdd();
            //更新标记
            signList.clear();
            List<Integer> ids = new ArrayList<>();
            ids.add(getIndex(row,col));
            signList.add(new AroundSign(ids,"#00000000","#6600FF00",1.2f));
            if (step == 2){
                gameTip = "白第二手不能走在棋盘中心的5*5区域";
                for (int i = 7; i <= 11 ; i++) {
                    for (int j = 7; j <= 11; j++){
                        signList.add(new ColorSign(getIndex(i,j), "#77333333"));
                    }
                }
            }
            else{
                gameTip = "-1";
            }
            //以下吃子,五连规则
            if (checkFormation(value) > 0) {
                if (value == 1) {
                    doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
                } else {
                    doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
                }
                return;
            }
            for (int i = 0; i<=7;i++){
                int[][] dir = {{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1}};  // 八个方向，direction
                if (0<=3*dir[i][0]+row && 3*dir[i][0]+row<=18 && 0<=3*dir[i][1]+col && 3*dir[i][1] + col<=18){  //判断该方向上有无三个
                    if (curGrids[3*dir[i][0]+row][3*dir[i][1]+col] == value && curGrids[2*dir[i][0]+row][2*dir[i][1]+col] == 3-value && curGrids[dir[i][0]+row][dir[i][1]+col] == 3-value) {  //3-value使得1,2互换
                        curGrids[2*dir[i][0] + row][2 * dir[i][1] + col] = 0;
                        ids.add(getIndex(2*dir[i][0]+row,2*dir[i][1]+col));
                        signList.add(new AroundSign(ids,"#00000000","#6600FF00",1.2f));
                        curGrids[dir[i][0] + row][dir[i][1] + col] = 0;
                        ids.add(getIndex(dir[i][0]+row,dir[i][1]+col));
                        signList.add(new AroundSign(ids,"#00000000","#6600FF00",1.2f));
                        if (value==1){
                            blackScore ++;
                            if (blackScore == 5){
                                doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
                                return;
                            }
                        }
                        else {whiteScore++;
                            if (whiteScore == 5){
                                doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
                                return;
                            }
                        }
                    }
                }
            }

            // 以上吃子,五连规则
            if (value == 1){
                noticeWhiteMove();
            }
            else {
                //和棋判定，因为2不改变奇偶性，所以只有白走完可能和棋
                if (step-2*(blackScore+whiteScore) == 361){  //19*19==361棋子
                    doOver(WinMode.BOTH_DRAW,player_black.getNickNameOrTemp() + "-黑棋战平" + player_white.getNickNameOrTemp() + "-白棋");
                    return;
                }
                noticeBlackMove();
            }
        }
    }

    //获取成5的次数,抄的五子棋
    private int checkFormation(int value) {
        int rows = curGrids.length;
        int cols = curGrids[0].length;
        int formationCount = 0;

        // 水平方向
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols - 4; j++) {
                int length = 0;
                for (int k = j; k < j + 5; k++) {
                    if (curGrids[i][k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= 5) {
                    formationCount += (length - 4);
                }
            }
        }

        // 垂直方向
        for (int i = 0; i < rows - 4; i++) {
            for (int j = 0; j < cols; j++) {
                int length = 0;
                for (int k = i; k < i + 5; k++) {
                    if (curGrids[k][j] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= 5) {
                    formationCount += (length - 4);
                }
            }
        }

        // 左上到右下方向
        for (int i = 0; i < rows - 4; i++) {
            for (int j = 0; j < cols - 4; j++) {
                int length = 0;
                for (int k = 0; k < 5; k++) {
                    if (curGrids[i + k][j + k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= 5) {
                    formationCount += (length - 4);
                }
            }
        }

        // 右上到左下方向
        for (int i = 0; i < rows - 4; i++) {
            for (int j = 4; j < cols; j++) {
                int length = 0;
                for (int k = 0; k < 5; k++) {
                    if (curGrids[i + k][j - k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= 5) {
                    formationCount += (length - 4);
                }
            }
        }

        return formationCount;
    }
}


